// Copyright DustedPixels.com 2008. All rights reserved.

package com.dustedpixels.jasmin.chips;

/**
 * @author micapolos@gmail.com (Michal Pociecha-Los)
 */
public final class Glue implements Chip {
  private final Incrementor incrementor1;
  private final Incrementor incrementor2;
  private final Memory memory;

  public Glue(Incrementor incrementor1, Incrementor incrementor2, Memory memory) {
    this.incrementor1 = incrementor1;
    this.incrementor2 = incrementor2;
    this.memory = memory;
  }
  
  public void update() {
    boolean addressActive = 
      incrementor1.ADDRESS_ACTIVE &&
      incrementor2.ADDRESS_ACTIVE && 
      memory.ADDRESS_ACTIVE;
    
    if (addressActive) {
      int address = incrementor1.ADDRESS;
      if (incrementor2.ADDRESS_ACTIVE) address = incrementor2.ADDRESS;
      if (memory.ADDRESS_ACTIVE) address = memory.ADDRESS;
    
      if (!incrementor1.ADDRESS_ACTIVE) incrementor1.ADDRESS = address;
      if (!incrementor2.ADDRESS_ACTIVE) incrementor2.ADDRESS = address;
      if (!memory.ADDRESS_ACTIVE) memory.ADDRESS = address;
    }

    boolean dataActive = 
      incrementor1.DATA_ACTIVE &&
      incrementor2.DATA_ACTIVE && 
      memory.DATA_ACTIVE;
    
    if (dataActive) {
      byte data = incrementor1.DATA;
      if (incrementor2.DATA_ACTIVE) data = incrementor2.DATA;
      if (memory.DATA_ACTIVE) data = memory.DATA;
    
      if (!incrementor1.DATA_ACTIVE) incrementor1.DATA = data;
      if (!incrementor2.DATA_ACTIVE) incrementor2.DATA = data;
      if (!memory.DATA_ACTIVE) memory.DATA = data;
    }

    boolean wrActive = 
      incrementor1.DATA_ACTIVE &&
      incrementor2.DATA_ACTIVE && 
      memory.DATA_ACTIVE;
    
    if (wrActive) {
      byte wr = incrementor1.DATA;
      if (incrementor2.DATA_ACTIVE) wr = incrementor2.DATA;
      if (memory.DATA_ACTIVE) wr = memory.DATA;
    
      if (!incrementor1.DATA_ACTIVE) incrementor1.DATA = wr;
      if (!incrementor2.DATA_ACTIVE) incrementor2.DATA = wr;
      if (!memory.DATA_ACTIVE) memory.DATA = wr;
    }

    boolean reqActive = 
      incrementor1.DATA_ACTIVE &&
      incrementor2.DATA_ACTIVE && 
      memory.DATA_ACTIVE;
    
    if (reqActive) {
      byte req = incrementor1.DATA;
      if (incrementor2.DATA_ACTIVE) req = incrementor2.DATA;
      if (memory.DATA_ACTIVE) req = memory.DATA;
    
      if (!incrementor1.DATA_ACTIVE) incrementor1.DATA = req;
      if (!incrementor2.DATA_ACTIVE) incrementor2.DATA = req;
      if (!memory.DATA_ACTIVE) memory.DATA = req;
    }
  } 
}
